package com.bird.framework.thread.factory;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import com.bird.common.constant.Constants;
import com.bird.common.utils.IpUtil;
import com.bird.common.utils.LogUtil;
import com.bird.common.utils.ServletUtil;
import com.bird.common.utils.SpringUtil;
import com.bird.framework.config.BirdConfig;
import com.bird.framework.utils.SecurityUtils;
import com.bird.system.domain.bo.LoginUser;
import com.bird.system.domain.entity.SysErrorLogEntity;
import com.bird.system.domain.entity.SysLogininforEntity;
import com.bird.system.domain.entity.SysOperLogEntity;
import com.bird.system.enums.LoginTypeEnum;
import com.bird.system.service.ISysErrorLogService;
import com.bird.system.service.ISysLogininforService;
import com.bird.system.service.ISysOperLogService;
import eu.bitwalker.useragentutils.UserAgent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.TimerTask;

/**
 * 异步工厂（产生任务用）
 *
 * @author bird
 */
public class AsyncFactory {

	private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");

	/**
	 * 记录登陆信息
	 *
	 * @param username 用户名
	 * @param status   状态
	 * @param message  消息
	 * @param args     列表
	 * @return 任务task
	 */
	public static TimerTask recordLogininfor(final String username, final LoginTypeEnum loginType, final String status, final String message,
											 final Object... args) {
		final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtil.getRequest().getHeader("User-Agent"));
		final String ip = IpUtil.getIpAddr(ServletUtil.getRequest());
		return new TimerTask() {
			@Override
			public void run() {

				StringBuilder s = new StringBuilder();
				s.append(LogUtil.getBlock(ip));
				String address = null;
				if (BirdConfig.isAddressEnabled()) {
					address = IpUtil.getAddress(ip);
					s.append(address);
				}
				s.append(LogUtil.getBlock(username));
				s.append(LogUtil.getBlock(status));
				s.append(LogUtil.getBlock(loginType.getValue()));
				s.append(LogUtil.getBlock(message));
				// 打印信息到日志
				sys_user_logger.info(s.toString(), args);
				// 获取客户端操作系统
				String os = userAgent.getOperatingSystem().getName();
				// 获取客户端浏览器
				String browser = userAgent.getBrowser().getName();
				// 封装对象
				SysLogininforEntity logininfor = new SysLogininforEntity();
				logininfor.setUserName(username);
				logininfor.setIpaddr(ip);
				logininfor.setLoginLocation(address);
				logininfor.setBrowser(browser);
				logininfor.setOs(os);
				logininfor.setLoginType(loginType.getValue());
				logininfor.setMsg(message);
				// 日志状态
				if (Constants.System.LOGIN_SUCCESS.equals(status) || Constants.System.LOGOUT.equals(status)) {
					logininfor.setStatus(Constants.System.SUCCESS);
				} else if (Constants.System.LOGIN_FAIL.equals(status)) {
					logininfor.setStatus(Constants.System.FAIL);
				}
				// 插入数据
				SpringUtil.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
			}
		};
	}

	/**
	 * 操作日志记录
	 *
	 * @param operLog 操作日志信息
	 * @return 任务task
	 */
	public static TimerTask recordOper(final SysOperLogEntity operLog) {
		return new TimerTask() {
			@Override
			public void run() {
				// 远程查询操作地点
				if (BirdConfig.isAddressEnabled()) {
					operLog.setOperLocation(IpUtil.getAddress(operLog.getOperIp()));
				}
				SpringUtil.getBean(ISysOperLogService.class).insertOperlog(operLog);
			}
		};
	}

	/**
	 * 错误日志记录
	 *
	 * @param e 错误信息
	 * @return 任务task
	 */
	public static TimerTask recordError(Throwable e) {
		final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtil.getRequest().getHeader("User-Agent"));
		final String ip = IpUtil.getIpAddr(ServletUtil.getRequest());
		final LoginUser loginUser = SecurityUtils.getLoginUser(true);
		final HttpServletRequest request = ServletUtil.getRequest();
		final String requestURI = request.getRequestURI();
		final String method = request.getMethod();
		String requestParams = null;
		if ("POST".equals(method) || "PUT".equals(method)) {
			requestParams = ServletUtil.getBody(request);
		} else {
			Map<String, String> paramMap = ServletUtil.getParamMap(request);
			if (paramMap != null) {
				requestParams = JSON.toJSONString(paramMap);
			}
		}
		final String finalRequestParams = requestParams;
		String address = IpUtil.getAddress(ip);
		if (BirdConfig.isAddressEnabled()) {
			address = IpUtil.getAddress(ip);
		}
		final String finalAddress = address;
		return new TimerTask() {
			@Override
			public void run() {
				final SysErrorLogEntity sysErrorLogEntity = new SysErrorLogEntity();
				sysErrorLogEntity.setUserAgent(userAgent.getOperatingSystem() + " " + userAgent.getBrowser());
				sysErrorLogEntity.setIpAddress(finalAddress);
				sysErrorLogEntity.setIp(ip);
				sysErrorLogEntity.setRequestMethod(method);
				sysErrorLogEntity.setRequestParams(finalRequestParams);
				sysErrorLogEntity.setRequestUri(requestURI);
				sysErrorLogEntity.setErrorSimpleInfo(ExceptionUtil.getRootCauseMessage(e));
				sysErrorLogEntity.setErrorInfo(ExceptionUtil.stacktraceToString(e));
				if (loginUser != null) {
					sysErrorLogEntity.setCreator(loginUser.getUser().getId());
					sysErrorLogEntity.setCreatorName(loginUser.getUsername());
				}
				SpringUtil.getBean(ISysErrorLogService.class).insert(sysErrorLogEntity);
			}
		};
	}
}
